package com.haoxi.subdsmp;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.TimerTask;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.haoxi.gateway.common.GatewayInfo;
import com.haoxi.gateway.common.SQLConst;
import com.haoxi.gateway.runner.smscommand.SubmitCmd;
import com.haoxi.gateway.util.Base64;
import com.haoxi.gateway.util.db.DBConnectUtil;

public class SubDSMP extends TimerTask {
    private final static Log log = LogFactory.getLog(SubDSMP.class);
    private static GatewayInfo gatewayInfo;
    private static String dbName;

    /**
     * @param gatewayInfo The gatewayInfo to set.
     */
    public static void setGatewayInfo(GatewayInfo gatewayInfo) {
        SubDSMP.gatewayInfo = gatewayInfo;
    }

    public void run() {
        if (gatewayInfo.getOpCode() == 0) {
            action();
        } else if (gatewayInfo.getOpCode() == 1) {
            action_LT();
        }
    }

    private int isDealed(int id, String dbName) {
        Connection conn = null;
        PreparedStatement stat = null;
        int index = -1;
        try {
            conn = DBConnectUtil.open(dbName);
            stat = conn.prepareStatement(SQLConst.UPDATE_DEALED_SUBSCRIBEREQ);
            stat.setInt(1, id);
            index = stat.executeUpdate();
        } catch (Exception e) {
            log.error("isDealed:", e);
        } finally {
            try {
                if (stat != null)
                    stat.close();
            } catch (Exception e) {
            }

            try {
                if (conn != null)
                    conn.close();
            } catch (Exception e) {
                log.error("isDealed:", e);
            }
        }
        return index;
    }

    public String getSubscribeReq(String msgType, String transactionID,
            String sendAddr_DeviceType, String sendAddr_DeviceID,
            String destAddr_DeviceType, String destAddr_DeviceID,
            int feeIDType, String feeMobile, String feePseudoCode,
            String destIDType, String destMobile, String destPseudoCode,
            String serviceIDType, String serviceID, String featureMobile,
            String featureContent, String spid, String AccessNo) {
        String str = "";

        str = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
        str = str
                + "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" ";
        str = str
                + "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" ";
        str = str + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ";
        str = str + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ";
        str = str
                + "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\" ";
        str = str + "xmlns=\"http://www.monternet.net/dsmp/schemas/\">\n";

        str = str + "<SOAP-ENV:Header>\n";
        str = str
                + "<TransactionID xmlns=\"http://www.monternet.net/dsmp/schemas/\" xsi:type=\"xsd:string\">"
                + transactionID + "</TransactionID>\n";
        str = str + "</SOAP-ENV:Header>\n";
        str = str + "<SOAP-ENV:Body>\n";
        if (msgType.equals("SubscribeServiceReq"))
            str = str
                    + "<SubscribeServiceReq xmlns=\"http://www.monternet.net/dsmp/schemas/\">\n";
        else if (msgType.equals("UnSubscribeServiceReq"))
            str = str
                    + "<UnSubscribeServiceReq xmlns=\"http://www.monternet.net/dsmp/schemas/\">\n";
        // str = str + "<TransactionID>" + transactionID + "</TransactionID>\n";
        str = str + "<Version>1.5.0</Version>\n";
        if (msgType.equals("SubscribeServiceReq"))
            str = str + "<MsgType>SubscribeServiceReq</MsgType>\n";
        else if (msgType.equals("UnSubscribeServiceReq"))
            str = str + "<MsgType>UnSubscribeServiceReq</MsgType>\n";
        str = str + "<Send_Address>\n";
        str = str + "<DeviceType>" + sendAddr_DeviceType + "</DeviceType>\n";
        str = str + "<DeviceID>" + sendAddr_DeviceID + "</DeviceID>\n";
        str = str + "</Send_Address>\n";
        str = str + "<Dest_Address>\n";
        str = str + "<DeviceType>" + destAddr_DeviceType + "</DeviceType>\n";
        str = str + "<DeviceID>" + destAddr_DeviceID + "</DeviceID>\n";
        str = str + "</Dest_Address>\n";
        str = str + "<FeeUser_ID>\n";
        str = str + "<UserIDType>" + feeIDType + "</UserIDType>\n";
        if (feeMobile == null || feeMobile.equals("null"))
            str = str + "<MSISDN></MSISDN>\n";
        else
            str = str + "<MSISDN>" + feeMobile + "</MSISDN>\n";
        if (feePseudoCode == null || feePseudoCode.equals("null"))
            str = str + "<PseudoCode/>\n";
        else
            str = str + "<PseudoCode>" + feePseudoCode + "</PseudoCode>\n";
        str = str + "</FeeUser_ID>\n";
        str = str + "<DestUser_ID>\n";
        str = str + "<UserIDType>" + destIDType + "</UserIDType>\n";
        if (destMobile == null || destMobile.equals("null"))
            str = str + "<MSISDN/>\n";
        else
            str = str + "<MSISDN>" + destMobile + "</MSISDN>\n";
        if (destPseudoCode == null || destPseudoCode.equals("null"))
            str = str + "<PseudoCode/>\n";
        else
            str = str + "<PseudoCode>" + destPseudoCode + "</PseudoCode>\n";
        str = str + "</DestUser_ID>\n";
        str = str + "<Service_ID>\n";
        str = str + "<ServiceIDType>" + serviceIDType + "</ServiceIDType>\n";
        str = str + "<SPID>" + spid + "</SPID>\n";
        str = str + "<SPServiceID>" + serviceID + "</SPServiceID>\n";
        if (serviceIDType.equals("2")) {
            str = str + "<AccessNo>" + AccessNo + "</AccessNo>\n";
            String featureStr = featureMobile + " " + featureContent;
            featureStr = Base64.encode(featureStr);
            str = str + "<FeatureStr>" + featureStr + "</FeatureStr>";
        } else {
            str = str + "<AccessNo/>\n"; // + "<AccessNo>" +spid+
            str = str + "<FeatureStr/>\n";
        }
        str = str + "</Service_ID>\n";
        if (msgType.equals("SubscribeServiceReq")) {
            if (serviceIDType.equals("2")) {
                String featureStr = featureMobile + " " + featureContent;
                featureStr = Base64.encode(featureStr);
                str = str + "<FeatureStr>" + featureStr + "</FeatureStr>\n";
            } else
                str = str + "<FeatureStr/>\n";
            str = str + "</SubscribeServiceReq>\n";
        } else if (msgType.equals("UnSubscribeServiceReq")) {
            str = str + "<FeatureStr/>\n";
            str = str + "</UnSubscribeServiceReq>\n";
        }
        str = str + "</SOAP-ENV:Body>\n";
        str = str + "</SOAP-ENV:Envelope>\n";

        return str;
    }

    /**
     * post����
     * 
     * @param xmlStr String ���������??
     * @param despUrl String dsmp��ַ
     */
    public int httpPost(String xmlStr, String despUrl, String gatewaycode,
            String serviceid, String mobile, String dbName) {
        URL url = null;
        OutputStream out = null;
        InputStream is = null;
        URLConnection urlConn = null;
        HttpURLConnection httpConn = null;
        int index = -1;

        try {
            byte[] arrB = xmlStr.getBytes("UTF-8");

            url = new URL(despUrl); // dsmp��ַ
            urlConn = url.openConnection();
            httpConn = (HttpURLConnection) urlConn;

            httpConn.setDoInput(true);
            httpConn.setDoOutput(true);
            httpConn.setRequestMethod("POST"); // POST ��ʽ��ע��POSTҪ��д
            httpConn.setRequestProperty("Content-Type",
                    "text/xml; charset=utf-8");
            httpConn.setRequestProperty("Content-Length", "" + arrB.length);
            httpConn.setRequestProperty("host", "www.monternet.com");

            out = httpConn.getOutputStream();
            out.write(arrB);
            out.flush();
            out.close();

            // �ӷ�������зֽ����?
            is = httpConn.getInputStream();
            index = getSubscribeResp(is, gatewaycode, serviceid, mobile, dbName);
            is.close();
        } catch (Exception e) {
            log.error("", e);
            index = -1;
        } finally {
            try {
                if (out != null)
                    out.close();
            } catch (Exception e) {
            }

            try {
                if (is != null)
                    is.close();
            } catch (Exception e) {
            }
        }
        return index;
    }

    public int getSubscribeResp(InputStream is, String gatewaycode,
            String serviceid, String mobile, String dbName) {
        // SAXBuilder sax = new SAXBuilder();
        int res = -1;
        try {
            StringBuffer sb = new StringBuffer();
            String MsgType = null;
            String TransactionID = null;
            String LinkID = null;
            String hRet = null;
            String Version = null;

            BufferedReader in = new BufferedReader(new InputStreamReader(is,
                    "UTF-8"));
            for (String line = ""; (line = in.readLine()) != null;) {
                sb.append(line);
                // sb.append("\n");
                // log.error("line =" + line);
                int pos = -1;
                int endPos = -1;
                pos = line.indexOf("<MsgType>");
                // log.error("pos =" + pos);
                if (pos >= 0) {
                    endPos = line.indexOf("</MsgType>");
                    MsgType = line.substring(pos + 9, endPos);
                    log.debug("MsgType =" + MsgType);
                    pos = -1;
                }
                pos = line
                        .indexOf("<TransactionID xmlns=\"http://www.monternet.net/dsmp/schemas/\" xsi:type=\"xsd:string\">");
                if (pos >= 0) {
                    endPos = line.indexOf("</TransactionID>");
                    TransactionID = line.substring(pos + 84, endPos);
                    log.debug("TransactionID =" + TransactionID);
                    pos = -1;
                }

                if (MsgType != null && MsgType.equals("SubscribeServiceResp")) {
                    pos = line.indexOf("<LinkID>");
                    if (pos >= 0) {
                        endPos = line.indexOf("</LinkID>");
                        LinkID = line.substring(pos + 8, endPos);
                        log.debug("LinkID =" + LinkID);
                        pos = -1;
                    }
                }

                pos = line.indexOf("<hRet>");
                if (pos >= 0) {
                    endPos = line.indexOf("</hRet>");
                    hRet = line.substring(pos + 6, endPos);
                    log.debug("hRet =" + hRet);
                    if (hRet.equals("0") || hRet.equals("115")) {
                        String abc = DealCancel(gatewaycode, serviceid, mobile,
                                dbName);
                        if (abc.equals("0"))
                            log.debug("DealCancel() OK! ");
                        else
                            log.debug("DealCancel() ܣ�?" + abc);
                    }
                    pos = -1;
                }

                pos = line.indexOf("<Version>");
                if (pos >= 0) {
                    endPos = line.indexOf("</Version>");
                    Version = line.substring(pos + 9, endPos);
                    log.debug("Version =" + Version);
                    pos = -1;
                }
            }
            // System.out.println(sb.toString());
            res = saveSubscribeResp(MsgType, TransactionID, hRet, LinkID,
                    gatewayInfo.getGatewayCode(), dbName);
        } catch (Exception e) {
            log.error("getSubscribeResp has a Exception :", e);
        }
        return res;
    }

    public String DealCancel(String gatewaycode, String serviceid,
            String mobile, String dbName) {
        Connection conn = null;
        CallableStatement cstat = null;
        String flag = "-1";
        try {
            conn = DBConnectUtil.open(dbName);
            cstat = conn.prepareCall(SQLConst.DEAL_SUBSCRIBEREQ);

            log.debug("gatewaycode:" + gatewaycode);
            log.debug("mobile:" + mobile);
            log.debug("serviceid:" + serviceid);
            cstat.setString(1, gatewaycode);
            cstat.setString(2, mobile);
            cstat.setString(3, serviceid);
            cstat.registerOutParameter(4, java.sql.Types.VARCHAR);
            cstat.execute();
            flag = cstat.getString(4);
        } catch (Exception e) {
            log.error("DealCancel() has a exception:", e);
        } finally {
            try {
                if (cstat != null)
                    cstat.close();
            } catch (Exception e) {
            }

            try {
                if (conn != null)
                    conn.close();
            } catch (Exception e) {
            }
        }
        return flag;
    }

    public int saveSubscribeResp(String msgType, String transactionID,
            String hRet, String linkID, String gatewaycode, String dbName) {
        Connection conn = null;
        PreparedStatement preStat = null;
        int index = 0;
        try {
            conn = DBConnectUtil.open(dbName);
            preStat = conn.prepareStatement(SQLConst.SAVE_SUBSCRIBEREQ);
            preStat.setString(1, msgType);
            preStat.setString(2, transactionID);
            preStat.setString(3, hRet);
            preStat.setString(4, linkID);
            preStat.setString(5, gatewaycode);
            index = preStat.executeUpdate();
        } catch (Exception e) {
            log.error("saveSubscribeResp has a Exception :", e);
        } finally {
            try {
                if (preStat != null)
                    preStat.close();
            } catch (Exception e) {
            }

            try {
                if (conn != null)
                    conn.close();
            } catch (Exception e) {
                log.error("", e);
            }
        }
        return index;
    }

    private void action_LT() {
        log.debug("Start deal need subdsmp date ....");
        if (null == dbName) {
            log.error("DB's name is null, please check it !");
            return;
        }
        Connection conn = null;
        PreparedStatement pstat = null;
        ResultSet rs = null;
        String gatewayCode = gatewayInfo.getGatewayCode();
        List reqList = new ArrayList();
        try {
            conn = DBConnectUtil.open(dbName);
            pstat = conn
                    .prepareStatement(SQLConst.SELECT_NEED_DEAL_SUBSCRIBEREQ_LT);
            log.debug("sql=="+SQLConst.SELECT_NEED_DEAL_SUBSCRIBEREQ_LT);
            pstat.setString(1, gatewayCode);
            rs = pstat.executeQuery();
            while (rs.next()) {
                String[] args = new String[4];
                args[0] = rs.getString("ID");
                args[1] = rs.getString("SERVICETAG");
                args[2] = rs.getString("USERNUBMER");
                reqList.add(args);
            }
        } catch (Exception e) {
            log.error("subscribereq:" + e, e);
        } finally {
            try {
                if (rs != null)
                    rs.close();
            } catch (Exception e) {
            }

            try {
                if (pstat != null)
                    pstat.close();
            } catch (Exception e) {
            }

            try {
                if (conn != null)
                    conn.close();
            } catch (Exception e) {
            }
        }
        Iterator iter = reqList.iterator();
        String opURL = gatewayInfo.getOpName();
        String url = "";
        while (iter.hasNext()) {
            String[] args = (String[]) iter.next();
            url = opURL + "?serviceTag=" + args[1] + "&userNumber=" + args[2];
            log.debug("requseturl==" + url);
            args[3] = getUrlResult(url);
            log.debug("result==" + args[3]);
        }
        int[] res = updateBatchSubscriberreq(reqList);
        if (res != null) {
            log.debug("update batch ResultSet size [" + res.length + "]");
        }

    }

    public int[] updateBatchSubscriberreq(List reqList) {
        int[] result = null;
        if (null == reqList || reqList.size() <= 0) {
            return null;
        }
        Connection conn = null;
        PreparedStatement pst = null;

        try {
            conn = DBConnectUtil.open(dbName);
            pst = conn
                    .prepareStatement(SQLConst.UPDATE_NEED_DEAL_SUBSCRIBEREQ_LT);
            log.debug("sql=="+SQLConst.UPDATE_NEED_DEAL_SUBSCRIBEREQ_LT);
            Iterator it = reqList.iterator();
            while (it.hasNext()) {
                String[] args = (String[]) it.next();
                pst.setString(1, args[3]);// res
                pst.setString(2, args[0]);// id
                pst.addBatch();
            }
            result = pst.executeBatch();

        } catch (SQLException sqle) {
            log.error("SQLException in " + dbName + ".saveMsgHistory()!", sqle);
        } finally {
            try {
                if (pst != null) {
                    pst.close();
                }
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException sqle) {
                log.error("release db connection unsuccessfully in " + dbName
                        + ".saveMsgHistory()!", sqle);
            }
        }

        return result;
    }

    public String getUrlResult(String urlString) {
        String mainString = new String();
        String mainString1 = new String();
        BufferedReader br = null;
        try {
            urlString = urlString.replaceAll(" ", "");
            URL url = new URL(urlString);
            // 打开到此URL 的连接并返回一个用于从该连接读入的 InputStream。
            br = new BufferedReader(new InputStreamReader(url.openStream()));
            while (br != null && (mainString1 = br.readLine()) != null) {
                if (!mainString1.equals("")) {
                    mainString += mainString1;
                }
            }
        } catch (Exception e) {
            // e.printStackTrace();
            log.error("spTools" + e.getMessage(), e);
            log.error("URL:[" + urlString + "] error " + e.getMessage());
            if (e.getMessage().length() > 30) {
                mainString = e.getMessage().substring(0, 30);
            } else {
                mainString = e.getMessage();
            }
        } finally {
            try {
                if (br != null) {
                    br.close();
                    br = null;
                }
            } catch (Exception e) {
                log.error("spTools" + e.getMessage(), e);
            }
            br = null;
        }
        return mainString;
    }

    private void action() {
        log.debug("Start deal need subdsmp data ...");
        /**
         * �?要的数据库名
         */
        if (null == dbName) {
            log.error("DB's name is null, please check it !");
            return;
        }
        Connection conn = null;
        PreparedStatement pstat = null;
        ResultSet rs = null;

        int id = 0;
        String msgType = null;
        String transactionID = null;
        String sendAddr_DeviceType = null;
        String sendAddr_DeviceID = null;
        String destAddr_DeviceType = null;
        String destAddr_DeviceID = null;
        int feeIDType = 0;
        String feeMobile = null;
        String feePseudoCode = null;
        String destIDType = null;
        String destMobile = null;
        String destPseudoCode = null;
        String serviceIDType = null;
        String serviceID = null;
        String featureMobile = null;
        String featureContent = null;
        String gatewaycode = null;
        String spid = null;
        String AccessNo = gatewayInfo.getSpNumber();
        String gatewayCode = gatewayInfo.getGatewayCode();
        // gatewayInfo.getOpCode();
        try {
            conn = DBConnectUtil.open(dbName);
            pstat = conn
                    .prepareStatement(SQLConst.SELECT_NEED_DEAL_SUBSCRIBEREQ);
            pstat.setString(1, gatewayCode);
            rs = pstat.executeQuery();
            while (rs.next()) {
                id = rs.getInt("id");
                msgType = rs.getString("MsgType");
                transactionID = rs.getString("TransactionID");
                sendAddr_DeviceType = rs.getString("SendAddr_DeviceType");
                sendAddr_DeviceID = rs.getString("SendAddr_DeviceID");
                destAddr_DeviceType = rs.getString("DestAddr_DeviceType");
                destAddr_DeviceID = rs.getString("destAddr_DeviceID");
                feeIDType = rs.getInt("FeeIDType");
                feeMobile = rs.getString("feeMobile");
                feePseudoCode = rs.getString("feePseudoCode");
                destIDType = rs.getString("DestIDType");
                destMobile = rs.getString("DestMobile");
                destPseudoCode = rs.getString("DestPseudoCode");
                serviceIDType = rs.getString("ServiceIDType");
                serviceID = rs.getString("ServiceID");
                featureMobile = rs.getString("FeatureMobile");
                featureContent = rs.getString("FeatureContent");
                gatewaycode = rs.getString("gatewaycode");
                spid = rs.getString("spid");

                // AccessNo = "8166";
                // if (gatewaycode.equals("1860"))
                // AccessNo = "8166";

                String subscribeStr = getSubscribeReq(msgType, transactionID,
                        sendAddr_DeviceType, sendAddr_DeviceID,
                        destAddr_DeviceType, destAddr_DeviceID, feeIDType,
                        feeMobile, feePseudoCode, destIDType, destMobile,
                        destPseudoCode, serviceIDType, serviceID,
                        featureMobile, featureContent, spid, AccessNo);
                log.debug("subscribeStr:" + subscribeStr);
                String subscribeUrl = "http://dsmp.gd.monternet.com/dsmp/dsmp.wsdl";
                int res = httpPost(subscribeStr, subscribeUrl, gatewaycode,
                        serviceID, destMobile, dbName);
                log.debug("httpPost(subscribeStr, subscribeUrl):" + res);

                log.debug("DeleteNeedChat(mobile)::" + isDealed(id, dbName));
            }
        } catch (Exception e) {
            log.error("subscribereq:" + e + " msgType =" + msgType
                    + " transactionID=" + transactionID + "transactionID = "
                    + transactionID + " sendAddr_DeviceType = "
                    + sendAddr_DeviceType + "sendAddr_DeviceID = "
                    + sendAddr_DeviceID + " destAddr_DeviceType = "
                    + destAddr_DeviceType + "destAddr_DeviceID = "
                    + destAddr_DeviceID + " feeIDType = " + feeIDType
                    + "feeMobile = " + feeMobile + " feePseudoCode = "
                    + feePseudoCode + "  destIDType = " + destIDType
                    + "destMobile = " + destMobile + " destPseudoCode ="
                    + destPseudoCode + "  serviceIDType = " + serviceIDType
                    + "serviceID = " + serviceID + " featureMobile = "
                    + featureMobile + "  featureContent = " + featureContent
                    + "gatewaycode = " + gatewaycode + " spid = " + spid
                    + " AccessNo =" + AccessNo, e);
        } finally {
            try {
                if (rs != null)
                    rs.close();
            } catch (Exception e) {
            }

            try {
                if (pstat != null)
                    pstat.close();
            } catch (Exception e) {
            }

            try {
                if (conn != null)
                    conn.close();
            } catch (Exception e) {
            }
        }
        log.debug("Start deal need subdsmp data ...");
    }

    /**
     * @param dbName The dbName to set.
     */
    public static void setDbName(String dbName) {
        SubDSMP.dbName = dbName;
    }

    public static void main(String[] args) {
        List list = new ArrayList();
        String[] par = new String[5];
        par[0] = "123";
        par[1] = "456";
        par[2] = "789";
        list.add(par);
        Iterator iter = list.iterator();
        while (iter.hasNext()) {
            String[] ppp = (String[]) iter.next();
            ppp[3] = "11111";
        }
        System.out.print(par[3]);

    }
}